package top.lshaci.learning.oauth2.client.config;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * Oauth2ClientConfig
 *
 * @author lshaci
 * @since 1.0.0
 */
@Slf4j
@Configuration
@EnableWebSecurity
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class Oauth2ClientConfig extends ResourceServerConfigurerAdapter {

    /**
     * 1、配置远程 token 校验
     *  org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration
     *      $RemoteTokenServicesConfiguration
     *          $TokenInfoServicesConfiguration
     *      1）配置校验 token 地址：security.oauth2.resource.token-info-uri=http://localhost:12000/oauth/check_token
     *      2）注入 RemoteTokenServices 使用即可
     *
     * 2、配置本地 jwttoken 校验
     *  org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerTokenServicesConfiguration
     *      $JwtTokenServicesConfiguration
     *      1）配置获取公钥地址：security.oauth2.resource.jwt.key-uri=http://localhost:12000/oauth/token_key
     *      2）注入 DefaultTokenServices(name=jwkTokenServices) 使用即可
     *
     * 3、【本地】校验优先级高于【远程】校验
     */
    @Autowired
    private DefaultTokenServices jwkTokenServices;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("res1");
        resources.tokenServices(jwkTokenServices);
        // 无权限的处理器
        resources.accessDeniedHandler((request, response, accessDeniedException) -> {
            response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            Map<String, Object> map = new HashMap<>(2);
            map.put("code", 40003);
            map.put("msg", "您没有权限进行此操作");
            response.getWriter().write(JSONUtil.toJsonStr(map));
        });
        // 身份验证的入口 (invalid_token  or  no_token)
        resources.authenticationEntryPoint((request, response, authException) -> {
            response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            Map<String, Object> map = new HashMap<>(2);
            map.put("code", 40001);
            map.put("msg", "请登录");
            response.getWriter().write(JSONUtil.toJsonStr(map));
        });

    }

}
